package com.cjack.frenchexcel.util;

import lombok.extern.slf4j.Slf4j;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

@Slf4j
public class DateFormatUtil {

    public final static String DATE_RULE_1 = "yyyy年MM月dd日 HH:mm:ss";
    public final static String DATE_RULE_2 = "yyyy-MM-dd";
    public final static String DATE_RULE_3 = "yyyy-MM-dd HH:mm:ss";
    public final static String DATE_RULE_4 = "yyMM";
    public final static String DATE_RULE_5 = "yyyy-MM";
    public final static String DATE_RULE_6 = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'";
    public final static String DATE_RULE_7 = "dd-MM-yyyy";
    public final static String DATE_RULE_8 = "yyyy年MM月";
    public final static String DATE_RULE_9 = "yyyy/M/d";
    public final static String DATE_RULE_10 = "MMyy";
    public final static String DATE_RULE_12 = "d/M/yyyy";
    public final static String DATE_RULE_11 = "ddMMyy";
    public final static String DATE_RULE_13 = "MMyyyy";
    public final static String DATE_RULE_14 = "dd/MM/yyyy";
    public final static String DATE_RULE_15 = "yyyy/MM/dd";

    public static String format(Date date, String rule) {
        if (date == null) {
            return null;
        }
        DateFormat df = new SimpleDateFormat(rule);
        return df.format(date);
    }

    /**
     * 返回当前月份的第一天
     *
     * @return yyyy-MM-dd
     */
    public static String formatCurrMonth() {
        DateFormat df = new SimpleDateFormat(DATE_RULE_2);
        Calendar c = Calendar.getInstance();
        c.setTimeInMillis(System.currentTimeMillis());
        c.set(Calendar.DAY_OF_MONTH, 1);
        return df.format(c.getTime());
    }

    /**
     * 返回当前时间前N天的日期
     *
     * @param day n
     * @return
     */
    public static String formatLastDay(int day) {
        DateFormat df = new SimpleDateFormat(DATE_RULE_2);
        Calendar c = Calendar.getInstance();
        c.setTimeInMillis(System.currentTimeMillis());
        c.add(Calendar.DATE, -day);
        return df.format(c.getTime());
    }

    public static String format(String dateStr, String rule) {
        DateFormat df = new SimpleDateFormat(rule);
        try {
            return df.format(df.parse(dateStr));
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println(dateStr);
            try {
                Date d = new Date(dateStr);
                return df.format(d);
            } catch (Exception e2) {
                e2.printStackTrace();
                return dateStr;
            }

        }
    }


    public static String format(String time, String timeFormat, String timeAfterFormat) {
        SimpleDateFormat sf = new SimpleDateFormat(timeFormat);
        Date date;
        try {
            date = sf.parse(time);
        } catch (ParseException e) {
            e.printStackTrace();
            return other(time, timeAfterFormat);
        }
        SimpleDateFormat dateFormat = new SimpleDateFormat(timeAfterFormat);
        time = dateFormat.format(date);
        return time;
    }

    private static String other(String time, String timeAfterFormat) {
        log.info("需要转换的日期：" + time);
        List<String> ruleList = new ArrayList();
        String rule;
        ruleList.add(DATE_RULE_1);
        ruleList.add(DATE_RULE_2);
        ruleList.add(DATE_RULE_3);
        ruleList.add(DATE_RULE_6);
        ruleList.add(DATE_RULE_7);
        ruleList.add(DATE_RULE_15);
        Date date;
        for (String s : ruleList) {
            rule = s;
            SimpleDateFormat sf = new SimpleDateFormat(rule);
            try {
                date = sf.parse(time);
                SimpleDateFormat dateFormat = new SimpleDateFormat(timeAfterFormat);
                String timeReturn = dateFormat.format(date);
                log.info("日期格式：" + time + "匹配日期格式：" + rule + "返回日期格式：" + timeReturn);
                return timeReturn;
            } catch (ParseException e) {
                log.info("日期格式：" + time + "不匹配日期格式：" + rule);
                e.printStackTrace();
            }
        }
        log.info("日期格式全部不匹配" + time);
        return time;
    }

    public static Date formatToDate(String dateStr, String rule) {
        DateFormat df = new SimpleDateFormat(rule);
        try {
            return df.parse(dateStr);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }


    //010721这种格式
    public static String formatSpecial2(String dateStr, String rule) {
        String[] strs = dateStr.split("");
        DateFormat df = new SimpleDateFormat(rule);
        try {
            Calendar c = Calendar.getInstance();
            c.set(Calendar.YEAR, Integer.valueOf("20" + Integer.valueOf(strs[4] + "" + strs[5])));
            c.set(Calendar.MONTH, Integer.valueOf(strs[2] + "" + strs[3]) - 1);
            c.set(Calendar.DAY_OF_MONTH, Integer.valueOf(strs[0] + "" + strs[1]));
            return df.format(c.getTime());
        } catch (Exception e) {
            e.printStackTrace();
            return dateStr;
        }
    }

    /**
     * @param dateStr 22/05/20
     * @param rule
     * @return
     */
    public static String formatSpecial(String dateStr, String rule) {
        String[] dataArr = dateStr.split("/");

        DateFormat df = new SimpleDateFormat(rule);
        try {
            Calendar c = Calendar.getInstance();
            c.set(Calendar.YEAR, Integer.valueOf("20" + dataArr[2]));
            c.set(Calendar.MONTH, Integer.valueOf(dataArr[1]) - 1);
            c.set(Calendar.DAY_OF_MONTH, Integer.valueOf(dataArr[0]));
            return df.format(c.getTime());
        } catch (Exception e) {
            return dateStr;
        }
    }


    public static Date parse(String dateStr) {
        DateFormat df = new SimpleDateFormat(DATE_RULE_2);
        try {
            return df.parse(dateStr);
        } catch (ParseException e) {
            e.printStackTrace();
            return null;
        }
    }

    public static Date parse2(String dateStr) {
        DateFormat df = new SimpleDateFormat(DATE_RULE_14);
        try {
            return df.parse(dateStr);
        } catch (ParseException e) {
            e.printStackTrace();
            return null;
        }
    }

    public static Date parseWithMinute(String dateStr) {
        DateFormat df = new SimpleDateFormat(DATE_RULE_3);
        try {
            return df.parse(dateStr);
        } catch (ParseException e) {
            e.printStackTrace();
            return null;
        }
    }

    public static Long handleDealTime(String dealTime) {
        DateFormat df = new SimpleDateFormat(DATE_RULE_2);
        Long timeStamps = null;
        try {
            timeStamps = df.parse(dealTime).getTime();
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return timeStamps;
    }

    /**
     * 根据传入的月份获取今年该月份的起止时间
     *
     * @return 0是开始时间，1是结束时间
     */
    public static Date[] getTimeByMonth(String month) {
        Date[] results = new Date[2];
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.set(Calendar.MONTH, Integer.valueOf(month) - 1);//calendar的 与月相关的设置都是从0开始的计算的
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        results[0] = calendar.getTime();
        calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH) + 1);//获取当月最后一天，把月份+1,再把日期-1
        calendar.set(Calendar.DAY_OF_MONTH, calendar.get(Calendar.DAY_OF_MONTH) - 1);
        results[1] = calendar.getTime();
        return results;
    }

    /**
     * 把法国时区的时间转换为中国时区的时间
     *
     * @param oldDateStr 法国时区的时间
     * @return 中国时区的时间
     */
    public static String frenchTimeToChina(String oldDateStr) {
        DateFormat df = new SimpleDateFormat(DATE_RULE_3);
        Date oldDate = null;
        try {
            oldDate = df.parse(df.format(new Date(oldDateStr)));
        } catch (Exception e) {
            try {
                oldDate = df.parse(oldDateStr);
            } catch (ParseException ex) {
                ex.printStackTrace();
            }
        }
        //计算法国时间的方式  当前中国时间 - 偏移小时
        Long time = oldDate.getTime() - getTimeDiff();
        return df.format(time);
    }

    /**
     * 把中国时区的时间转换为法国时区的时间
     *
     * @param oldDateStr 中国时区的时间
     * @return 法国时区的时间
     */
    public static String chinaTimeToFrench(String oldDateStr) {
        DateFormat df = new SimpleDateFormat(DATE_RULE_3);
        Date oldDate = null;
        try {
            oldDate = df.parse(df.format(new Date(oldDateStr)));
        } catch (Exception e) {
            try {
                oldDate = df.parse(oldDateStr);
            } catch (ParseException ex) {
                ex.printStackTrace();
            }
        }
        //计算法国时间的方式  当前中国时间 + 偏移小时
        Long time = oldDate.getTime() + getTimeDiff();
        return df.format(time);
    }

    /**
     * 获取当前时间所处是冬令时间，还是夏令时间
     * 夏令时间（4-10月份），返回7,冬令时间（其他时间），返回6
     *
     * @return
     */
    private static Integer getTimeDiff() {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        int month = calendar.get(Calendar.MONTH) + 1;
        if (month >= 4 && month <= 10) {
            return 7;
        } else {
            return 6;
        }
    }

    public static void main(String[] args) {
        System.out.println(formatSpecial2("080822", DATE_RULE_11));
    }

    /**
     * date2比date1多的天数
     *
     * @param date1
     * @param date2
     * @return
     */
    public static int differentDays(Date date1, Date date2) {
        Calendar cal1 = Calendar.getInstance();
        cal1.setTime(date1);
        Calendar cal2 = Calendar.getInstance();
        cal2.setTime(date2);
        int day1 = cal1.get(Calendar.DAY_OF_YEAR);
        int day2 = cal2.get(Calendar.DAY_OF_YEAR);
        int year1 = cal1.get(Calendar.YEAR);
        int year2 = cal2.get(Calendar.YEAR);
        if (year1 != year2) {   //不同一年
            int timeDistance = 0;
            for (int i = year1; i < year2; i++) {
                if (i % 4 == 0 && i % 100 != 0 || i % 400 == 0) {    //闰年
                    timeDistance += 366;
                } else {    //不是闰年
                    timeDistance += 365;
                }
            }
            return timeDistance + (day2 - day1);
        } else {    //同一年
            System.out.println("判断day2 - day1 : " + (day2 - day1));
            return day2 - day1;
        }
    }

    /**
     * 获取当前时间的月份,注意月份要加1
     *
     * @return
     */
    public static Integer getMonth() {
        Calendar cal = Calendar.getInstance();
        cal.setTimeInMillis(System.currentTimeMillis());
        return cal.get(Calendar.MONTH) + 1;
    }

    /**
     * 获取传入时间的绝对月份,注意月份要加1
     *
     * @return
     */
    public static Integer getMonth(String dateStr) {
        Calendar cal = Calendar.getInstance();
        Date consumerDate = DateFormatUtil.parse(dateStr);
        cal.setTime(consumerDate);
        return cal.get(Calendar.YEAR) * 12 + cal.get(Calendar.MONTH) + 1;
    }

    /**
     * 获取当前时间的月份
     *
     * @return
     */
    public static Integer getYear() {
        Calendar cal = Calendar.getInstance();
        cal.setTimeInMillis(System.currentTimeMillis());
        return cal.get(Calendar.YEAR);
    }

    /**
     * 获取前面第N天0点的时间
     *
     * @return
     */
    public static Date getLastDayZero(int lastDay) {
        Calendar cal = Calendar.getInstance();
        cal.setTimeInMillis(System.currentTimeMillis());
        cal.set(Calendar.DAY_OF_MONTH, cal.get(Calendar.DAY_OF_MONTH) - lastDay);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        return cal.getTime();
    }

    /**
     * 获取前面第N天0点的时间
     *
     * @return
     */
    public static String getLastDayZeroForStr(int lastDay) {
        Calendar cal = Calendar.getInstance();
        cal.setTimeInMillis(System.currentTimeMillis());
        cal.set(Calendar.DAY_OF_MONTH, cal.get(Calendar.DAY_OF_MONTH) - lastDay);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        return format(cal.getTime(), DATE_RULE_3);
    }

    /**
     * 获取当前时间前一个月1号的0点时间
     *
     * @return
     */
    public static Date getLastMonthZero() {
        Calendar cal = Calendar.getInstance();
        cal.setTimeInMillis(System.currentTimeMillis());
        cal.set(Calendar.MONTH, cal.get(Calendar.MONTH) - 1);
        cal.set(Calendar.DAY_OF_MONTH, 1);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        return cal.getTime();
    }

    /**
     * 获取当前时间前一个月1号的0点时间
     *
     * @return
     */
    public static String getLastNMonthZero(int n) {
        Calendar cal = Calendar.getInstance();
        cal.setTimeInMillis(System.currentTimeMillis());
        cal.set(Calendar.MONTH, cal.get(Calendar.MONTH) - n);
        cal.set(Calendar.DAY_OF_MONTH, 1);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        return format(cal.getTime(), DATE_RULE_3);
    }

    public static String getMonthLastDay(String dateStr) {
        Date date = parse(dateStr);
        Calendar cal = Calendar.getInstance();
        cal.setTimeInMillis(date.getTime());
        cal.set(Calendar.MONTH, cal.get(Calendar.MONTH) + 1);
        cal.set(Calendar.DAY_OF_MONTH, 1);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        return format(cal.getTime(), DATE_RULE_3);
    }

    public static String getMonthLastDay2(String dateStr) {
        Date date = parse2(dateStr);
        Calendar cal = Calendar.getInstance();
        cal.setTimeInMillis(date.getTime());
        cal.set(Calendar.DATE, 1);
        cal.add(Calendar.MONTH, 1);
        cal.add(Calendar.DATE, -1);
        return format(cal.getTime(), DATE_RULE_14);
    }

    /**
     * 获取当前时间上周周一的时间，这里把当前时间减去7天即可
     *
     * @return
     */
    public static Date getLastWeekZero() {
        Calendar cal = Calendar.getInstance();
        cal.setTimeInMillis(System.currentTimeMillis());
        cal.set(Calendar.DAY_OF_MONTH, cal.get(Calendar.DAY_OF_MONTH) - 7);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        return cal.getTime();
    }

    /**
     * 获取当前时间前6个月的数据
     *
     * @return
     */
    public static String getTimeCountByMonth() {
        Calendar cal = Calendar.getInstance();
        cal.setTimeInMillis(System.currentTimeMillis());
        cal.add(Calendar.MONTH, -6);
        DateFormat df = new SimpleDateFormat(DATE_RULE_2);
        return df.format(cal.getTime());
    }

    //把钱的显示格式，从 5623.66 转换成 5 623,66
    public static String handleMoneyShowStyle(Double money) {
        Integer i = Integer.valueOf(String.valueOf(money).split("\\.")[0]);
        String x = String.valueOf(money).split("\\.")[1];
        StringBuilder sb = new StringBuilder();
        sb.append(i / 1000 > 0 ? i / 1000 : "").append(" ");
        sb.append(i % 1000);
        sb.append(",").append(x);
        return sb.toString();
    }

    public static String getLastMonthStr() {
        Calendar cal = Calendar.getInstance();
        cal.setTimeInMillis(System.currentTimeMillis());
        cal.add(Calendar.MONTH, -1);
        DateFormat df = new SimpleDateFormat(DATE_RULE_8);
        return df.format(cal.getTime());
    }
}
